package hichecker.university;

import hichecker.controller.MainController;
import hichecker.ui.custom_views.passing.PassingCondition;
import hichecker.ui.custom_views.passing.PassingCondition.ConditionType;
import hichecker.ui.custom_views.requirement.RequirementSettings;
import hichecker.ui.custom_views.requirement.RequirementView;
import hichecker.ui.general_views.container_panel.content.ContentPanel;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

/**
 * Class representing a requirement a student has to take to be authorized for the exam or he needs
 * for his course grade
 */
@XmlType(propOrder = {"id", "passingCondition"})
public abstract class Requirement extends UniversityPart {

	private @XmlAttribute String name;

	private @XmlElement UUID id;
	private @XmlElement PassingCondition passingCondition;

	/**
	 * Creates a new requirement and generates a new unique id
	 */
	public Requirement() {
		id = UUID.randomUUID();
	}

	/**
	 * Creates a new requirement with a referenced id
	 *
	 * @param id
	 */
	public Requirement(UUID id) {
		this.id = id;
	}

	/**
	 * Creates a new requirement and copies all values out of the referenced requirement
	 *
	 * @param requirement
	 */
	public Requirement(Requirement requirement) {
		id = requirement.getID();
		name = requirement.getName();
		passingCondition = requirement.getPassingCondition();
	}

	@Override
	@XmlTransient
	public UUID getID() {
		return id;
	}

	/**
	 * @param id the unique id to set
	 */
	public void setID(UUID id) {
		this.id = id;
	}

	@Override
	@XmlTransient
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return all conditions which must be fullfilled to pass this requirement
	 */
	@XmlTransient
	public PassingCondition getPassingCondition() {
		return passingCondition;
	}

	/**
	 * @param passingConditions the conditions to set
	 */
	public void setPassingConditions(PassingCondition passingCondition) {
		this.passingCondition = passingCondition;
	}

	/**
	 * Returns the sum of max points of all series related to this requirement
	 *
	 * @param student
	 */
	public abstract float getMaxPoints();

	/**
	 * Returns the sum of gained points of all series related to this requirement by a referenced
	 * student
	 *
	 * @param student
	 */
	public abstract float getSumPoints(Student student);


	@Override
	public List<ConditionType> getPossibleConditions() {
		List<ConditionType> list = new ArrayList<ConditionType>();
		list.add(ConditionType.SUBS_PASSED);
		list.add(ConditionType.SUM_POINTS_GREATER_EQUAL);

		return list;
	}

	@Override
	public ContentPanel getRepresentation(boolean showConfig, MainController controller) {
		return showConfig ? new RequirementSettings(this, controller) : new RequirementView(this,
				controller);
	}

	@Override
	public UniversityPart[] getPossibleSubPart() {
		return new UniversityPart[] { new PTLSeries() };
	}

	/**
	 * Two requirements are equal if they have the same {@link #getID() id}
	 */
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof Requirement))
			return false;
		Requirement that = (Requirement) o;
		return that.id.equals(this.id);
	}
}
